package com.liang.blog.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.liang.blog.common.exception.BlogException;
import com.liang.blog.common.result.ResultCodeEnum;
import com.liang.blog.model.BlogUser;
import com.liang.blog.model.constant.CacheConstants;
import com.liang.blog.security.jwt.AuthContextHolder;
import com.liang.blog.system.mapper.BlogUserMapper;
import com.liang.blog.system.service.BlogMenuService;
import com.liang.blog.system.service.BlogUserService;
import com.liang.blog.vo.menu.MenuPermissionVo;
import com.liang.blog.vo.user.LoginUserVo;
import com.liang.blog.vo.user.RegisterVo;
import com.liang.blog.vo.user.UserInfoVo;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author：YanWenLiang
 * @Date:2023-08-16-20:58
 */
@Service
public class BlogUserServiceImpl implements BlogUserService {

    @Autowired
    private BlogUserMapper blogUserMapper;

    @Autowired
    private BlogMenuService blogMenuService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 分页获取用户信息
     * @return
     */
    @Override
    public List<UserInfoVo> getUserInfoPage(UserInfoVo userInfoVo) {
        return blogUserMapper.getUserInfoPage(userInfoVo);
    }

    /**
     * 根据用户 id 逻辑删除用户
     * @param id
     * @return
     */
    @Override
    public int deleteUserById(Long id) {
        return blogUserMapper.deleteUserById(id);
    }

    /**
     * 根据用户账号获取用户信息
     * @param account
     * @return
     */
    @Override
    public BlogUser getUserByAccount(String account) {
        return blogUserMapper.getUserByAccount(account);
    }

    /**
     * 根据用户 id 获取用户信息
     * @param id
     * @return
     */
    @Override
    public UserInfoVo getUserById(Long id) {
        return blogUserMapper.getUserById(id);
    }


    /**
     * 获取当前登入的用户信息
     * @param account
     * @return
     */
    @Override
    public LoginUserVo getLoginUserInfo(String account) {
        BlogUser blogUser = blogUserMapper.getUserByAccount(account);
        List<MenuPermissionVo> menuPermissionVos =
                blogMenuService.getMenuByRoleIdAndMenuId(blogUser.getRoleId());

        Set<String> permissions = new HashSet<>();
        if (blogUser.getId() == 1){
            permissions.add("*:*:*");
        } else {
            // 用户权限集合
            permissions = menuPermissionVos.stream()
                    .map(MenuPermissionVo::getPerms)
                    .filter(perm -> perm != null && !perm.isEmpty())
                    .collect(Collectors.toSet());
        }

        LoginUserVo loginUserVo = new LoginUserVo();
        loginUserVo.setPermissions(permissions);
        loginUserVo.setBlogUser(blogUser);
        return loginUserVo;
    }

    /**
     * 设置登入 ip
     * @param ip
     * @param updateTime
     */
    @Override
    public void setLoginIp(String ip, Date updateTime, String account) {
        blogUserMapper.setLoginIp(ip, updateTime, account);
    }

    /**
     * 修改用户状态
     * @param status
     * @param id
     * @return
     */
    @Override
    public int updateUserStatus(int status, String id) {
        return blogUserMapper.updateUserStatus(status, id);
    }

    /**
     * 根据用户id 修改用户信息
     * @param userInfoVo
     * @return
     */
    @Override
    public int updateUserById(UserInfoVo userInfoVo) {
        userInfoVo.setUpdateTime(new Date());
        return blogUserMapper.updateUserById(userInfoVo);
    }

    /**
     * 保存用户
     * @param registerVo
     * @return
     */
    @Override
    public Boolean saveUser(RegisterVo registerVo) {
        if (!ObjectUtil.isAllNotEmpty(registerVo.getAccount(), registerVo.getPassword(), registerVo.getEmail(), registerVo.getVerifyCode())){
            throw new BlogException(ResultCodeEnum.PARAM_ERROR);
        }

        return blogUserMapper.saveUser(registerVo) == 1;
    }

    /**
     * 获取用户数量
     * @param account
     * @return
     */
    @Override
    public Integer getUserCount(String account) {
        return blogUserMapper.getUserCount(account);
    }

    @Override
    public Integer getUserByEmailCount(String email) {
        return blogUserMapper.getUserByEmailCount(email);
    }

    @Override
    public BlogUser getUserByEmail(String email) {
        return blogUserMapper.getUserByEmail(email);
    }

    /**
     * 用户更新个人信息
     * @param userInfoVo 请求体
     * @author Liuzixin
     * @date 2024年05月08日
     */
    @Override
    public void updateUserForUs(HttpServletRequest request, UserInfoVo userInfoVo) {
        String emailCode = redisTemplate.opsForValue().get(CacheConstants.SYS_LOGIN_VERIFY_CODE_KEY + userInfoVo.getLoginUuid());
        if (StringUtils.isEmpty(emailCode)) {
            throw new BlogException(ResultCodeEnum.CODE_EXPIRED);
        }
        if (!StringUtils.equals(emailCode, userInfoVo.getEmailCode())) {
            throw new BlogException(ResultCodeEnum.CODE_ERROR);
        }
        this.updateUserById(userInfoVo);
    }
}
